﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace GestaltDesigner
{
    public partial class SelectionUI : UserControl
    {
        private bool _isMouseDown;
        private Point _startingPointSouthEast, _startingPointNorthWest, _handlePoint;

        public event EventHandler SizeOrPositionChanged;

        public SelectionUI()
        {
            InitializeComponent();

            _lowerRight.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _lowerRight.MouseMove += new MouseEventHandler(lowerRight_MouseMove);
            _lowerRight.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _lowerCenter.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _lowerCenter.MouseMove += new MouseEventHandler(lowerCenter_MouseMove);
            _lowerCenter.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _lowerLeft.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _lowerLeft.MouseMove += new MouseEventHandler(lowerLeft_MouseMove);
            _lowerLeft.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _middleLeft.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _middleLeft.MouseMove += new MouseEventHandler(middleLeft_MouseMove);
            _middleLeft.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _middleRight.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _middleRight.MouseMove += new MouseEventHandler(middleRight_MouseMove);
            _middleRight.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _upperCenter.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _upperCenter.MouseMove += new MouseEventHandler(upperCenter_MouseMove);
            _upperCenter.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _upperLeft.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _upperLeft.MouseMove += new MouseEventHandler(upperLeft_MouseMove);
            _upperLeft.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
            _upperRight.MouseLeftButtonDown += new MouseButtonEventHandler(mouseLeftButtonDown);
            _upperRight.MouseMove += new MouseEventHandler(upperRight_MouseMove);
            _upperRight.MouseLeftButtonUp += new MouseButtonEventHandler(mouseLeftButtonUp);
        }

        void ProcessMouseDown(FrameworkElement sender, MouseButtonEventArgs e)
        {
            _isMouseDown = true;
            Point mousePoint = e.GetPosition(this.Parent as UIElement);
            _startingPointSouthEast = new Point(mousePoint.X - (double)sender.GetValue(Canvas.LeftProperty) - this.Width, mousePoint.Y - (double)sender.GetValue(Canvas.TopProperty) - this.Height);
            _handlePoint = e.GetPosition(sender as UIElement);
            sender.CaptureMouse();
            e.Handled = true;
        }

        void ProcessMouseUp(FrameworkElement sender, MouseButtonEventArgs e)
        {
            _isMouseDown = false;
            sender.ReleaseMouseCapture();
        }

        void ProcessMouseMove(MouseEventArgs e, bool north, bool south, bool west, bool east)
        {
            if (_isMouseDown)
            {
                // move element & selection UI
                if (east)
                {
                    this.Width = Math.Max(e.GetPosition(this.Parent as UIElement).X - _startingPointSouthEast.X, 24);
                }

                if (south)
                {
                    this.Height = Math.Max(e.GetPosition(this.Parent as UIElement).Y - _startingPointSouthEast.Y, 24);
                }

                if (north)
                {
                    double oldTop = (double)this.GetValue(Canvas.TopProperty);
                    if (this.Height + oldTop - (double)this.GetValue(Canvas.TopProperty) > 24)
                    {
                        this.SetValue(Canvas.TopProperty, e.GetPosition(this.Parent as UIElement).Y - _handlePoint.Y);
                        this.Height = Math.Max(this.Height + oldTop - (double)this.GetValue(Canvas.TopProperty), 24);
                    }
                }

                if (west)
                {
                    double oldLeft = (double)this.GetValue(Canvas.LeftProperty);
                    if (this.Width + oldLeft - (double)this.GetValue(Canvas.LeftProperty) > 24)
                    {
                        this.SetValue(Canvas.LeftProperty, e.GetPosition(this.Parent as UIElement).X - _handlePoint.X);
                        this.Width = Math.Max(this.Width + oldLeft - (double)this.GetValue(Canvas.LeftProperty), 24);
                    }
                }

                if (this.SizeOrPositionChanged != null)
                {
                    this.SizeOrPositionChanged(this, new EventArgs());
                }
            }
        }

        void mouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ProcessMouseUp((FrameworkElement)sender, e);
        }

        void mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ProcessMouseDown((FrameworkElement)sender, e);
        }

        void lowerRight_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, false, true, false, true);
        }

        void lowerLeft_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, false, true, true, false);
        }

        void lowerCenter_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, false, true, false, false);
        }

        void middleRight_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, false, false, false, true);
        }

        void middleLeft_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, false, false, true, false);
        }

        void upperRight_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, true, false, false, true);
        }

        void upperLeft_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, true, false, true, false);
        }

        void upperCenter_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessMouseMove(e, true, false, false, false);
        }
    }
}
